﻿using Microsoft.AspNetCore.SignalR;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Threading.Channels;
using System.Threading;
using System.Threading.Tasks;
using Xiao.Code.Entities.Users;
using Xiao.Util;
using Xiao.Web.Code.VM.Hub;
using System.IO;

namespace Xiao.Web.Code.HubService
{
    public class ChatHub:Hub
    {
        private readonly IRedisUtil _redisUtil;
        public ChatHub(
            IRedisUtil redisUtil
            )
        {
            _redisUtil = redisUtil;
        }
        public override async Task OnConnectedAsync()
        {
            var token = Context.GetHttpContext().Request.Headers["Authorization"].ToString();
            var user=await _redisUtil.GetAsync<ConsumerDto>(token);
            if (user == null)
            {
                await OnDisconnectedAsync(new Exception("请先登录"));
                return;
            }
            var onT =await _redisUtil.SAdd("OnLine", user.Id);
           await _redisUtil.SetAsync(user.Id.ToString(), Context.ConnectionId);
        }
        public override async Task OnDisconnectedAsync(Exception exception)
        {
            var token = Context.GetHttpContext().Request.Headers["Authorization"].ToString();
            var user = await _redisUtil.GetAsync<ConsumerDto>(token);
            if (user == null) return;
            await _redisUtil.SRemAsync("OnLine", user.Id);
            await _redisUtil.DetleteAsync(user.Id.ToString());
        }
        /// <summary>
        /// 发送gps位置
        /// </summary>
        /// <param name="gps"></param>
        /// <returns></returns>
        public async Task Gps(string data)
        {
            var gps = JsonConvert.DeserializeObject<Gps>(data);
            var token = Context.GetHttpContext().Request.Headers["Authorization"].ToString();
            var user=await  _redisUtil.GetAsync<ConsumerDto>(token);
            var receive =await _redisUtil.GetAsync(gps.Receive.ToString());
            if (user == null||string.IsNullOrEmpty(receive)) return;
            gps.Id = user.Id;
            gps.Name = user.Name;
            gps.HeadPortrait = user.HeadPortrait;
            await Clients.Client(receive).SendAsync("data", JsonConvert.SerializeObject(gps));
        }
        /// <summary>
        /// 发送通知
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task SendMessage(string data)
        {
            var token = Context.GetHttpContext().Request.Headers["Authorization"].ToString();
            var user = _redisUtil.GetAsync<ConsumerDto>(token);
            var message = JsonConvert.DeserializeObject<HubMessageVM>(data);
            var receive = await _redisUtil.GetAsync(message.Receive.ToString());
            if (string.IsNullOrEmpty(receive)) return;
            message.User = user.Result;
            await Clients.Client(receive).SendAsync("message", JsonConvert.SerializeObject(message));
        }
        public async Task UploadStream(ChannelReader<byte[]> stream, string userId)
        {
            var token = await _redisUtil.GetAsync(userId);
            if (string.IsNullOrEmpty(token))
            {
                await OnDisconnectedAsync(new Exception("该用户不在线"));
                return;
            }
            while (await stream.WaitToReadAsync())
            {
                while (stream.TryRead(out var item))
                {
                    await Clients.Client(token).SendAsync("Counter", item);
                }
            }
        }
    }
}
